home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 June
/
CHIP Haziran 2001.iso
/
prog
/
haziran
/
19
/
setup.exe
/
data.z
/
kptest.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-04-11
|
5KB
|
134 lines
#include "../../../include/kpstdlib.h"
#include "../../../include/wd_kp.h"
#include "../kptest_com.h"
BOOL __cdecl KP_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData, PVOID *ppDrvContext);
void __cdecl KP_Close(PVOID pDrvContext);
void __cdecl KP_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, BOOL fIsKernelMode);
BOOL __cdecl KP_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, PVOID *ppIntContext);
void __cdecl KP_IntDisable(PVOID pIntContext);
BOOL __cdecl KP_IntAtIrql(PVOID pIntContext, BOOL *fIsMyInterrupt);
DWORD __cdecl KP_IntAtDpc(PVOID pIntContext, DWORD dwCount);
BOOL __cdecl KP_Init(KP_INIT *kpInit)
{
// check if the version of WD_KP.LIB is the same version as WINDRVR.H and WD_KP.H
if (kpInit->dwVerWD!=WD_VER)
{
// you need to re-compile your kernel plugin with the compatible version of WD_KP.LIB, WINDRVR.H and WD_KP.H!
return FALSE;
}
kpInit->funcOpen = KP_Open;
strcpy (kpInit->cDriverName, "KPTEST"); // until 8 chars
return TRUE;
}
// called when WD_KernelPlugInOpen() is called. pDrvContext returned will be passed to
// rest of the functions
BOOL __cdecl KP_Open(KP_OPEN_CALL *kpOpenCall, HANDLE hWD, PVOID pOpenData, PVOID *ppDrvContext)
{
kpOpenCall->funcClose = KP_Close;
kpOpenCall->funcCall = KP_Call;
kpOpenCall->funcIntEnable = KP_IntEnable;
kpOpenCall->funcIntDisable = KP_IntDisable;
kpOpenCall->funcIntAtIrql = KP_IntAtIrql;
kpOpenCall->funcIntAtDpc = KP_IntAtDpc;
*ppDrvContext = NULL; // you can allocate memory here
return TRUE;
}
// called when WD_KernelPlugInClose() is called
void __cdecl KP_Close(PVOID pDrvContext)
{
// you can free the memory allocated to pDrvContext here
}
// called when WD_KernelPlugInCall() is called
void __cdecl KP_Call(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, BOOL fIsKernelMode)
{
kpCall->dwResult = KPTEST_OK;
switch ( kpCall->dwMessage )
{
case KPTEST_MSG_VERSION: // in this sample we implement a GetVersion message
{
DWORD dwVer = 100;
KPTEST_VERSION *ver = (KPTEST_VERSION *) kpCall->pData;
COPY_TO_USER_OR_KERNEL(&ver->dwVer, &dwVer, sizeof(DWORD), fIsKernelMode);
COPY_TO_USER_OR_KERNEL(ver->cVer, "My Driver V1.00", sizeof("My Driver V1.00")+1, fIsKernelMode);
kpCall->dwResult = KPTEST_OK;
}
break ;
// you can implement other messages here
default:
kpCall->dwResult = KPTEST_NO_IMPL_MESSAGE;
}
}
// called when WD_IntEnable() is called, with a kernel plugin handler specified
// the pIntContext will be passed to the rest of the functions handling interrupts.
// returns TRUE if enable is succesful
BOOL __cdecl KP_IntEnable(PVOID pDrvContext, WD_KERNEL_PLUGIN_CALL *kpCall, PVOID *ppIntContext)
{
DWORD *pIntCount;
// you can allocate memory specific for each interrupt in *ppIntContext
*ppIntContext = malloc(sizeof (DWORD));
if (!*ppIntContext)
return FALSE;
// in this sample the information is a DWORD used to count the incomming interrupts
pIntCount = (DWORD *) *ppIntContext;
*pIntCount = 0; // reset the count to zero
return TRUE;
}
// called when WD_IntDisable() is called
void __cdecl KP_IntDisable(PVOID pIntContext)
{
// you can free the interrupt specific memory to pIntContext here
free(pIntContext);
}
// returns TRUE if needs DPC.
// this function is called at IRQL level - at physical interrupt handler.
// most library calls are NOT allowed, for example:
// NO WD_xxxx() calls, except WD_Transfer(),
// NO malloc,
// NO free
// YES WD_Transfer
// YES your functions, as long as they dont call library functions
// YES specific kernel functions, that the Win DDK specifically allows them to be
// called at IRQL
BOOL __cdecl KP_IntAtIrql(PVOID pIntContext, BOOL *pfIsMyInterrupt)
{
DWORD *pdwIntCount = (DWORD *) pIntContext;
// you should check your hardware here to see if the interrupt belongs to you.
// if in doubt, return FALSE (this is the safest)
*pfIsMyInterrupt = FALSE;
// in this example we will schedule a DPC once in every 5 interrupts
(*pdwIntCount) ++;
if (*pdwIntCount==5)
{
*pdwIntCount = 0;
return TRUE;
}
return FALSE;
}
// returns the number of times to notify user-mode (i.e. return from WD_IntWait)
DWORD __cdecl KP_IntAtDpc(PVOID pIntContext, DWORD dwCount)
{
return dwCount; // return WD_IntWait as many times as KP_IntAtIrql scheduled KP_IntAtDpc()
}